<template>
    <el-container class="layout">
        <el-aside :width="isCollapsed ? '64px' : '230px'" class="sidebar">
            <div class="brand">
                <div class="brand-avatar" v-if="!isCollapsed">{{ avatarInitial }}</div>
                <span class="brand-mark" v-if="!isCollapsed">仓库管理</span>
            </div>
            <div class="welcome-card" v-if="!isCollapsed">
                <div class="welcome-line">你好，<span class="welcome-user">{{ username || '用户' }}</span>，欢迎登录</div>
                <div class="welcome-role">{{ userRole || '未分配角色' }}</div>
                <div class="welcome-status"><span class="dot online"></span> 在线</div>
            </div>

            <div class="sidebar-search" v-if="!isCollapsed">
                <el-input v-model.trim="menuQuery" size="small" placeholder="搜索菜单功能" clearable :prefix-icon="Search" />
            </div>
            <el-menu ref="menuRef" class="menu" :collapse="isCollapsed" :default-active="activeKey"
                :unique-opened="true" :background-color="themeColors.menuBg" :text-color="themeColors.menuText"
                :active-text-color="themeColors.menuActiveText" @open="handleOpen">

                <template v-for="group in filteredMenu" :key="group.key">
                    <el-sub-menu v-if="group.children && group.children.length" :index="group.key">
                        <template #title>
                            <el-icon class="menu-icon">
                                <component :is="getIconComp(group.title)" />
                            </el-icon>
                            <span>{{ group.title }}</span>
                        </template>
                        <!-- 第二级：child -->
                        <template v-for="child in group.children" :key="child.key">
                            <!-- 有第三级时，作为子菜单展示 -->
                            <el-sub-menu v-if="child.children && child.children.length" :index="child.key">
                                <template #title>
                                    <el-icon class="menu-icon">
                                        <component :is="getIconComp(child.title)" />
                                    </el-icon>
                                    <span>{{ child.title }}</span>
                                </template>
                                <!-- 第三级：grandchild 作为叶子项 -->
                                <el-menu-item v-for="grand in child.children" :key="grand.key" :index="grand.key"
                                    @click="onSelect(grand)">
                                    <el-icon class="menu-icon">
                                        <component :is="getIconComp(grand.title)" />
                                    </el-icon>
                                    <span>{{ grand.title }}</span>
                                </el-menu-item>
                            </el-sub-menu>
                            <!-- 无第三级时，直接作为叶子项展示 -->
                            <el-menu-item v-else :index="child.key" @click="onSelect(child)">
                                <el-icon class="menu-icon">
                                    <component :is="getIconComp(child.title)" />
                                </el-icon>
                                <span>{{ child.title }}</span>
                            </el-menu-item>
                        </template>
                    </el-sub-menu>
                    <el-menu-item v-else :index="group.key" @click="onSelect(group)">
                        <el-icon class="menu-icon">
                            <component :is="getIconComp(group.title)" />
                        </el-icon>
                        <span>{{ group.title }}</span>
                    </el-menu-item>
                </template>
            </el-menu>
        </el-aside>

        <el-container>
            <el-header class="header">
                <div class="header-left">
                    <el-button class="collapse-btn" circle size="small" @click="isCollapsed = !isCollapsed">
                        <el-icon>
                            <Menu />
                        </el-icon>
                    </el-button>
                    <div class="hdr-title">仓库管理系统</div>
                    <el-breadcrumb separator="/" class="breadcrumbs">
                        <el-breadcrumb-item v-for="(m, index) in matchedRoutes" :key="m.path"
                            :class="{ 'is-clickable': index < matchedRoutes.length - 1 }"
                            @click="handleBreadcrumbClick(m, index)">
                            {{ m.meta?.title || m.name || m.path }}
                        </el-breadcrumb-item>
                    </el-breadcrumb>
                </div>
                <div class="header-actions">
                    <el-tooltip content="全屏">
                        <el-button circle size="small" @click="toggleFullscreen"><el-icon>
                                <FullScreen />
                            </el-icon></el-button>
                    </el-tooltip>
                    <el-tooltip content="主题">
                        <el-button circle size="small" @click="toggleTheme"><el-icon>
                                <Moon />
                            </el-icon></el-button>
                    </el-tooltip>
                    <el-tooltip content="通知">
                        <el-button circle size="small"><el-icon>
                                <Bell />
                            </el-icon></el-button>
                    </el-tooltip>
                    <el-divider direction="vertical" />
                    <el-icon class="hdr-icon">
                        <User />
                    </el-icon>
                    <div class="role-name">{{ userRole || '—' }}</div>
                    <el-dropdown>
                        <span class="el-dropdown-link">
                            页面操作<el-icon class="el-icon--right">
                                <ArrowDown />
                            </el-icon>
                        </span>
                        <template #dropdown>
                            <el-dropdown-menu>
                                <el-dropdown-item @click="goPersonalSettings">个人设置</el-dropdown-item>
                                <el-dropdown-item @click="refreshPage">刷新</el-dropdown-item>
                                <el-dropdown-item divided @click="handleLogout">退出登录</el-dropdown-item>
                            </el-dropdown-menu>
                        </template>
                    </el-dropdown>
                </div>
            </el-header>
            <el-main class="content">
                <div class="tabs-bar">
                    <div class="tabs-wrapper">
                        <el-tag v-for="t in tags" :key="t.fullPath"
                            :type="t.fullPath === currentPath ? 'success' : 'info'" class="tab-item" closable
                            @close="closeTag(t)" @click="router.push(t)">{{ t.meta?.title ||
                                t.name ||
                                t.path }}</el-tag>
                    </div>
                    <el-tooltip content="关闭全部标签">
                        <el-button size="small" circle @click="clearAllTags">
                            <el-icon>
                                <Delete />
                            </el-icon>
                        </el-button>
                    </el-tooltip>
                </div>
                <RouterView />
            </el-main>
        </el-container>
    </el-container>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import myaxios from '@/http/MyAxios'
import { Menu, User, SwitchButton, House, Box, Tickets, Setting, OfficeBuilding, UserFilled, Collection, Star, FullScreen, Moon, Bell, ArrowDown, Search, Delete } from '@element-plus/icons-vue'

type MenuItem = {
    key: string            // 菜单唯一键
    title: string          // 展示名称
    routePath?: string     // 路由名称
    children?: MenuItem[]
}

// 折叠/搜索
const isCollapsed = ref(false)
const menuQuery = ref('')

// 动态菜单树
const menuTree = ref<MenuItem[]>([])

// 已使用的 key 集合（仅运行期用于去重）
const usedKeys = new Set<string>()

// 将后端 { id, label, routeName, children } 映射为前端 MenuItem
const mapToMenu = (nodes: any[]): MenuItem[] => {
    return (nodes || []).map(n => {
        let key = n.routePath && typeof n.routePath === 'string' && n.routePath.length > 0
            ? String(n.routePath)
            : String(n.id ?? n.permissionId ?? '')
        if (!key || key === 'undefined' || key === 'null') {
            key = `m-${Math.random().toString(36).slice(2, 8)}`
        }
        // 去重：若重复则加后缀，避免 Element Plus 展开冲突
        let safeKey = key
        let i = 1
        while (usedKeys.has(safeKey)) {
            safeKey = `${key}#${i++}`
        }
        usedKeys.add(safeKey)
        if (import.meta.env?.DEV && safeKey !== key) {
            // console.debug('[menu] duplicate key fixed:', key, '=>', safeKey)
        }
        const item: MenuItem = {
            key: safeKey,
            title: n.label ?? n.permissionName ?? n.name ?? '未命名',
            routePath: n.routePath || ''
        }
        if (n.children && n.children.length) item.children = mapToMenu(n.children)
        return item
    })
}

// 加载当前用户可见菜单树
const loadUserMenu = () => {
    // 每次重新加载前清空已使用 key 集合
    usedKeys.clear()
    return myaxios({ url: '/api/Permission/GetMyPermissionTree', method: 'get' })
        .then(res => {
            // 兼容数组或 {code,data} 或 {code,data:{data}}
            let raw: any = []
            if (Array.isArray(res.data)) raw = res.data
            else if (Array.isArray(res.data?.data)) raw = res.data.data
            else if (Array.isArray(res.data?.data?.data)) raw = res.data.data.data
            const mapped: any = mapToMenu(raw)
            // 如果后端以单一根节点包裹（如“首页”），则展开其 children 作为顶级菜单
            const firstNode = mapped[0]
            if (mapped.length === 1 && firstNode && firstNode.children && firstNode.children.length) {
                menuTree.value = firstNode.children
            } else {
                menuTree.value = mapped
            }
        })

        .catch(err => {
            console.log('加载用户菜单失败:', err)
            menuTree.value = []
        })
}

const router = useRouter();
const route = useRoute();

// 顶部展示的角色名（从本地存储推断，可按你的登录返回调整字段）
const userRole = ref<string>('')
const username = ref<string>(localStorage.getItem('username') || '')
onMounted(() => {
    userRole.value = (localStorage.getItem('userRole') || localStorage.getItem('roleName') || localStorage.getItem('role') || '') as string
    username.value = localStorage.getItem('username') || ''
})

// 头像首字
const avatarInitial = computed(() => {
    const name = (username.value || localStorage.getItem('username') || localStorage.getItem('userAccount') || userRole.value || 'U') as string
    return String(name).trim().charAt(0).toUpperCase()
})

const activeKey = ref('')
const currentTitle = computed(() => {
    const findTitle = (nodes: MenuItem[], key: string): string | undefined => {
        for (const n of nodes) {
            if (n.key === key) return n.title
            if (n.children) {
                const t = findTitle(n.children, key)
                if (t) return t
            }
        }
    }
    return findTitle(menuTree.value, activeKey.value) || '首页'
})

function onSelect(item: MenuItem) {
    activeKey.value = item.key
    if (item.routePath) {
        router.push({ name: item.routePath }).catch(() => { })
    }
}

// 保证顶级只展开一个：当某个根菜单被打开时，关闭其他根菜单
const menuRef = ref()
function handleOpen(index: string, indexPath: string[]) {
    // 仅在顶级展开时处理（indexPath 长度为 1 表示根层）
    if (Array.isArray(indexPath) && indexPath.length === 1 && menuRef.value) {
        const rootKeys = (menuTree.value || [])
            .filter(it => it.children && it.children.length)
            .map(it => it.key)
        for (const k of rootKeys) {
            if (k !== index) {
                try { menuRef.value.close(k) } catch { }
            }
        }
    }
}

// 面包屑 - 过滤重复项，如果同时有"主页"和"首页"，只显示"首页"
const matchedRoutes = computed(() => {
    const routes = route.matched
    if (routes.length <= 1) return routes

    // 检查是否同时存在"主页"和"首页"
    let hasHome = false
    let hasMain = false

    for (const routeItem of routes) {
        const title = routeItem.meta?.title || routeItem.name || ''
        if (title === '首页') hasHome = true
        if (title === '主页') hasMain = true
    }

    // 如果同时存在，过滤掉"主页"
    if (hasHome && hasMain) {
        return routes.filter((routeItem: any) => {
            const title = routeItem.meta?.title || routeItem.name || ''
            return title !== '主页'
        })
    }

    return routes
})

// 面包屑点击跳转
const handleBreadcrumbClick = (routeItem: any, index: number) => {
    // 最后一项不跳转（当前页面）
    if (index === matchedRoutes.value.length - 1) {
        return
    }

    // 跳转到对应的路由
    const targetRoute = routeItem.path || routeItem.name
    if (targetRoute) {
        if (routeItem.name) {
            router.push({ name: routeItem.name }).catch(() => { })
        } else if (routeItem.path) {
            router.push(routeItem.path).catch(() => { })
        }
    }
}

// 多页签
const tags = ref<any[]>([])
const currentPath = computed(() => route.fullPath)

function pushTag(r: any) {
    if (!tags.value.find(t => t.fullPath === r.fullPath)) {
        tags.value.push({ fullPath: r.fullPath, path: r.path, name: r.name, meta: r.meta })
    }
}

function closeTag(t: any) {
    const idx = tags.value.findIndex(x => x.fullPath === t.fullPath)
    if (idx >= 0) {
        tags.value.splice(idx, 1)
        if (t.fullPath === currentPath.value) {
            const next = tags.value[idx - 1] || tags.value[idx] || { name: 'Main' }
            router.push(next).catch(() => { })
        }
    }
}

function clearAllTags() {
    const current = {
        fullPath: route.fullPath,
        path: route.path,
        name: route.name,
        meta: route.meta
    }
    tags.value = [current]
}

watch(() => route.fullPath, (fp) => {
    pushTag(route)
}, { immediate: true })

// 刷新、全屏、主题
function refreshPage() {
    location.reload()
}

function toggleFullscreen() {
    const el: any = document.documentElement
    if (!document.fullscreenElement) {
        el.requestFullscreen?.()
    } else {
        document.exitFullscreen?.()
    }
}

type ThemeName = 'dark' | 'light' | 'dim' | 'ocean'

const themeConfigs: Record<ThemeName, {
    vars: Record<string, string>
    menuBg: string
    menuText: string
    menuActiveText: string
}> = {
    dark: {
        vars: {
            '--layout-bg': '#0a1120',
            '--primary-text': '#e5e7eb',
            '--sidebar-bg': '#0e1627',
            '--sidebar-border': '#0b1220',
            '--brand-color': '#cbd5e1',
            '--menu-hover-bg': 'rgba(255, 255, 255, 0.08)',
            '--menu-active-bg': 'rgba(34, 197, 94, 0.22)',
            '--menu-active-border': '#22c55e',
            '--header-bg': '#0b1324',
            '--content-bg': '#0a1120',
            '--card-border': '#0a1020',
            '--welcome-text': '#cbd5e1',
            '--welcome-strong': '#e2e8f0',
            '--welcome-muted': '#94a3b8',
            '--status-dot': '#22c55e'
        },
        menuBg: '#0f172a',
        menuText: '#cbd5e1',
        menuActiveText: '#22c55e'
    },
    light: {
        vars: {
            '--layout-bg': '#f5f7fb',
            '--primary-text': '#1f2937',
            '--sidebar-bg': '#ffffff',
            '--sidebar-border': '#e5e7eb',
            '--brand-color': '#0f172a',
            '--menu-hover-bg': 'rgba(100, 116, 139, 0.12)',
            '--menu-active-bg': 'rgba(34, 197, 94, 0.15)',
            '--menu-active-border': '#22c55e',
            '--header-bg': '#ffffff',
            '--content-bg': '#f8fafc',
            '--card-border': '#e2e8f0',
            '--welcome-text': '#475569',
            '--welcome-strong': '#0f172a',
            '--welcome-muted': '#64748b',
            '--status-dot': '#22c55e'
        },
        menuBg: '#ffffff',
        menuText: '#475569',
        menuActiveText: '#22c55e'
    },
    dim: {
        vars: {
            '--layout-bg': '#111827',
            '--primary-text': '#f3f4f6',
            '--sidebar-bg': '#1f2937',
            '--sidebar-border': '#1e293b',
            '--brand-color': '#f3f4f6',
            '--menu-hover-bg': 'rgba(59, 130, 246, 0.18)',
            '--menu-active-bg': 'rgba(59, 130, 246, 0.25)',
            '--menu-active-border': '#3b82f6',
            '--header-bg': '#0f172a',
            '--content-bg': '#111827',
            '--card-border': '#1e293b',
            '--welcome-text': '#d1d5db',
            '--welcome-strong': '#f9fafb',
            '--welcome-muted': '#cbd5f5',
            '--status-dot': '#3b82f6'
        },
        menuBg: '#1f2937',
        menuText: '#e2e8f0',
        menuActiveText: '#3b82f6'
    },
    ocean: {
        vars: {
            '--layout-bg': '#e0f2fe',
            '--primary-text': '#0f172a',
            '--sidebar-bg': '#dbeafe',
            '--sidebar-border': '#c7d2fe',
            '--brand-color': '#1d4ed8',
            '--menu-hover-bg': 'rgba(59, 130, 246, 0.16)',
            '--menu-active-bg': 'rgba(14, 165, 233, 0.3)',
            '--menu-active-border': '#0ea5e9',
            '--header-bg': '#bfdbfe',
            '--content-bg': '#e0f2fe',
            '--card-border': '#c7d2fe',
            '--welcome-text': '#0f172a',
            '--welcome-strong': '#1d4ed8',
            '--welcome-muted': '#0f172a',
            '--status-dot': '#0ea5e9'
        },
        menuBg: '#dbeafe',
        menuText: '#0f172a',
        menuActiveText: '#0ea5e9'
    }
}

const themeOrder: ThemeName[] = ['dark', 'dim', 'ocean', 'light']
const storedTheme = localStorage.getItem('theme') as ThemeName | null
const defaultTheme: ThemeName = storedTheme && themeConfigs[storedTheme] ? storedTheme : 'dark'
const currentTheme = ref<ThemeName>(defaultTheme)
const themeColors = computed(() => themeConfigs[currentTheme.value])

function applyTheme(name: ThemeName) {
    const cfg = themeConfigs[name]
    if (!cfg) return
    Object.entries(cfg.vars).forEach(([key, value]) => {
        document.documentElement.style.setProperty(key, value)
    })
    localStorage.setItem('theme', name)
}

function toggleTheme() {
    const idx = themeOrder.indexOf(currentTheme.value)
    const nextIndex = idx >= 0 ? (idx + 1) % themeOrder.length : 0
    const next = themeOrder[nextIndex] ?? 'dark'
    currentTheme.value = next
    applyTheme(currentTheme.value)
}

onMounted(() => {
    applyTheme(currentTheme.value)
})

// 过滤菜单
function filterTree(nodes: MenuItem[], q: string): MenuItem[] {
    if (!q) return nodes
    const res: MenuItem[] = []
    const kw = q.toLowerCase()
    for (const n of nodes) {
        const title = (n.title || '').toLowerCase()
        const children = n.children ? filterTree(n.children, q) : []
        if (title.includes(kw) || (children && children.length)) {
            res.push({ ...n, children })
        }
    }
    return res
}
const filteredMenu = computed(() => filterTree(menuTree.value, menuQuery.value))

onMounted(() => {
    loadUserMenu()
    pushTag(route)
})

// 个人设置：根据已注册路由智能跳转
function goPersonalSettings() {
    const routes = router.getRoutes()
    // 优先匹配中文名称或 meta 标题为“个人设置”
    const byCn = routes.find(r => r.name === '个人设置' || r.meta?.title === '个人设置' || (typeof r.name === 'string' && r.name.includes('个人设置')))
    if (byCn) {
        router.push({ name: byCn.name as string }).catch(() => { })
        return
    }
    // 其次匹配 name/meta/title 包含 profile 或 personal
    const byEn = routes.find(r => {
        const n = String(r.name || '').toLowerCase()
        const t = String(r.meta?.title || '').toLowerCase()
        return n.includes('profile') || n.includes('personal') || t.includes('profile') || t.includes('个人')
    })
    if (byEn) {
        router.push({ name: byEn.name as string }).catch(() => { })
        return
    }
    // 兜底：尝试常见路径
    const byPath = routes.find(r => ['/Profile', '/profile', '/Personal', '/personal'].includes(r.path))
    if (byPath) {
        router.push({ path: byPath.path }).catch(() => { })
    }
}

// 图标选择（可按需要扩展映射）
function getIconComp(title: string) {
    const t = String(title || '').toLowerCase()
    if (t.includes('仓库') || t.includes('库')) return Box
    if (t.includes('组织') || t.includes('部门')) return OfficeBuilding
    if (t.includes('用户') || t.includes('人员')) return UserFilled
    if (t.includes('角色')) return Collection
    if (t.includes('权限')) return Tickets
    if (t.includes('设置') || t.includes('系统')) return Setting
    if (t.includes('首页') || t.includes('主页')) return House
    return Star
}

// 退出登录
function handleLogout() {
    try {
        localStorage.removeItem('token')
        localStorage.removeItem('authToken')
        localStorage.removeItem('userRole')
        sessionStorage.removeItem('token')
    } catch { }
    router.replace({ name: 'Login' })
}
</script>

<style scoped>
:global(:root) {
    --layout-bg: #0a1120;
    --primary-text: #e5e7eb;
    --sidebar-bg: #0e1627;
    --sidebar-border: #0b1220;
    --brand-color: #cbd5e1;
    --menu-hover-bg: rgba(255, 255, 255, 0.08);
    --menu-active-bg: rgba(34, 197, 94, 0.22);
    --menu-active-border: #22c55e;
    --header-bg: #0b1324;
    --content-bg: #0a1120;
    --card-border: #0a1020;
    --welcome-text: #cbd5e1;
    --welcome-strong: #e2e8f0;
    --welcome-muted: #94a3b8;
    --status-dot: #22c55e;
}

.layout {
    height: 100vh;
}

.sidebar {
    border-right: 1px solid var(--sidebar-border);
    background: var(--sidebar-bg);
    /* 深色统一 */
    box-shadow: inset -1px 0 0 rgba(0, 0, 0, .4);
    /* 仅菜单滚动，信息区固定 */
    display: flex;
    flex-direction: column;
}

.brand {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 16px;
    font-weight: 700;
    color: var(--brand-color);
    /* 与菜单前景一致 */
    border-bottom: 1px solid #0a1020;
    background: var(--sidebar-bg);
    /* 与菜单同色 */
    position: sticky;
    top: 0;
    z-index: 3;
}

.brand-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: linear-gradient(135deg, #22c55e, #16a34a);
    box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.15);
}

.menu {
    border-right: none;
    background: var(--sidebar-bg);
    /* 与侧栏同色 */
    padding: 6px;
    /* 仅菜单区滚动 */
    flex: 1 1 auto;
    overflow-y: auto;
}

.menu :deep(.el-sub-menu__title),
.menu :deep(.el-menu-item) {
    background: transparent;
    border-radius: 8px;
}

.menu :deep(.el-sub-menu__title:hover),
.menu :deep(.el-menu-item:hover) {
    background: var(--menu-hover-bg);
}

.menu :deep(.el-menu-item.is-active) {
    background: var(--menu-active-bg);
    border-right: 3px solid var(--menu-active-border);
}

/* 分组分隔线与层级留白 */
.menu :deep(.el-sub-menu) {
    margin-top: 6px;
}

.menu :deep(.el-sub-menu__title) {
    border: 1px solid rgba(255, 255, 255, 0.06);
}

.menu :deep(.el-menu-item) {
    margin: 2px 0;
}

.header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 16px;
    border-bottom: 1px solid rgba(0, 0, 0, .08);
    background: var(--header-bg);
    color: var(--primary-text);
    box-shadow: 0 2px 8px rgba(0, 0, 0, .12);
    min-height: 64px;
}

.header-title {
    font-weight: 700;
    color: #14532d;
}

.header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.header-left {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.breadcrumbs {
    white-space: normal;
    line-height: 20px;
}

.breadcrumbs :deep(.el-breadcrumb__item.is-clickable) {
    cursor: pointer;
}

.breadcrumbs :deep(.el-breadcrumb__item.is-clickable .el-breadcrumb__inner) {
    color: var(--el-text-color-primary);
    transition: color 0.2s;
}

.breadcrumbs :deep(.el-breadcrumb__item.is-clickable .el-breadcrumb__inner:hover) {
    color: var(--el-color-primary);
}

/* 标签条与内容区左右对齐，并略微增高 */
.tabs-bar {
    padding: 0;
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.tabs-wrapper {
    display: flex;
    flex: 1;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

.tabs-bar :deep(.el-tag) {
    height: 30px;
    line-height: 30px;
    padding: 0 10px;
}

.search {
    width: 220px;
}

.content {
    padding: 16px;
    background: var(--content-bg);
    color: var(--primary-text);
}

.placeholder {
    color: #64748b;
}

/* 头像欢迎卡片 */
.welcome-card {
    padding: 10px 12px;
    color: var(--welcome-text);
    font-size: 12px;
    border-bottom: 1px solid var(--card-border);
    position: sticky;
    top: 54px;
    z-index: 2;
}

.welcome-line {
    opacity: .9;
}

.welcome-role {
    margin-top: 4px;
    font-weight: 600;
    color: var(--welcome-strong);
}

.welcome-status {
    margin-top: 6px;
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--welcome-muted);
}

.welcome-status .dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
}

.welcome-status .dot.online {
    background: var(--status-dot);
    box-shadow: 0 0 10px rgba(34, 197, 94, .6);
}

/* 品牌头像圆块 */
.brand-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: linear-gradient(135deg, #22c55e, #16a34a);
    color: #fff;
    display: grid;
    place-items: center;
    font-weight: 700;
}
</style>
